﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using MathLib.Common;
using MBG.Extensions.Core;

namespace MathLib.Algebra
{
    public struct Variable
    {
        public string Name { get; set; }
        public int Exponent { get; set; }

        public Variable(string name, int exponent)
            : this()
        {
            Name = name;
            Exponent = exponent;
        }

        public static Variable Parse(string item)
        {
            Variable variable = new Variable();
            variable.Exponent = 1;

            Match match = CompiledRegex.VariablePattern.Match(item);

            if (match != null && !string.IsNullOrEmpty(match.Value))
            {
                variable.Name = match.Value;

                match = CompiledRegex.IntegerPattern.Match(item);
                {
                    if (match != null && !string.IsNullOrEmpty(match.Value))
                    {
                        variable.Exponent = int.Parse(match.Value);
                    }
                }
            }

            return variable;
        }

        public static bool operator ==(Variable lhs, Variable rhs)
        {
            if (lhs.Name == rhs.Name &&
                lhs.Exponent == rhs.Exponent)
            {
                return true;
            }
            return false;
        }
        public static bool operator !=(Variable lhs, Variable rhs)
        {
            return !(lhs == rhs);
        }

        public static Variable Empty
        {
            get { return new Variable(); }
        }

        public override string ToString()
        {
            if (Exponent.In(0, 1))
            { return Name; }
            else
            {
                return string.Concat(Name, '^', Exponent, '^');
            }
        }
    }
    public class VariableCollection : List<Variable>
    {
        public bool ContainsVariableName(string name)
        {
            return this.SingleOrDefault(x => x.Name == name) != default(Variable);
        }
        public bool Equals(VariableCollection v2)
        {
            if (this.Count() != v2.Count())
            { return false; }

            if (this.ToString() == v2.ToString())
            {
                return true;
            }
            return false;

            //if (this.Count() != v2.Count())
            //{ return false; }

            //IEnumerable<string> v1Names = this.Select(x => x.ToString());
            //IEnumerable<string> v2Names = v2.Select(x => x.ToString());

            //foreach (string vName in v1Names)
            //{
            //    if (!vName.In(v2Names))
            //    {
            //        return false;
            //    }
            //}

            //return true;
        }
        public override string ToString()
        {
            string variables = string.Empty;
            foreach (Variable variable in this.OrderBy(v => v.Name))
            {
                variables = string.Concat(variables, variable.ToString());
            }
            return variables;
        }
    }
}